#include <iostream>

using namespace std;

class Tools {
public:
    virtual ~Tools() = default;

public:
    virtual void doSomeThing() = 0;
};

class ATools : public Tools {
public:
    ~ATools() override = default;

public:
    void doSomeThing() override {
        cout << "Tools A Do Some Thing!" << endl;
    }
};

class BTools : public Tools {
public:
    ~BTools() override = default;

public:
    void doSomeThing() override {
        cout << "Tools B Do Some Thing!" << endl;
    }
};

class ProxyTools : public Tools {
public:
    explicit ProxyTools(Tools *tools) : tools(tools) {}

    ~ProxyTools() override {
        delete tools;
    }

private:
    Tools *tools = nullptr;

private:
    void init() {
        cout << "Object Init Working..." << endl;
    }

    void log() {
        cout << "Log Saving..." << endl;
    }

public:
    void doSomeThing() override {
        init();
        tools->doSomeThing();
        log();
    }
};

void test01() {
    Tools *tools = nullptr;

    tools = new ATools();
    tools->doSomeThing();
    cout << "-----------------------" << endl;
    tools = new ProxyTools(tools);
    tools->doSomeThing();

    delete tools;

    cout << endl;
}

void test02() {
    Tools *tools = nullptr;

    tools = new BTools();
    tools->doSomeThing();
    cout << "-----------------------" << endl;
    tools = new ProxyTools(tools);
    tools->doSomeThing();

    delete tools;

    cout << endl;
}


int main() {
    test01();

    test02();
}
